﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NUnit.Framework;
using NSsh.Common.Utility;
using NUnit.Framework.SyntaxHelpers;
using Rhino.Mocks;
using Rhino.Testing.AutoMocking;

namespace NSsh.Common.Tests.Utility
{
    [TestFixture]
    public class DependencyFixture
    {
        [SetUp]
        public void Setup()
        {
            Dependency.Clear();
        }

        [Test]
        public void ShouldResolveType()
        {
            Dependency.RegisterTransient<ITest, Test>("test");
            ITest test = Dependency.Resolve<ITest>();
            Assert.That(test, Is.Not.Null, "Expected non-null test service.");
        }

        [Test]
        public void ShouldResolveTypeByKey()
        {
            MockRepository mocks = new MockRepository();
            ITest alternativeService = mocks.CreateMock<ITest>();

            Dependency.RegisterTransient<ITest, Test>("test");
            Dependency.RegisterInstance<ITest>("alternativeService", alternativeService);

            ITest test = Dependency.Resolve<ITest>("test");

            Assert.That(test, Is.Not.Null, "Expected non-null service.");
            Assert.That(test, Is.InstanceOfType(typeof(Test)), "Correct type.");
            Assert.That(test, Is.Not.EqualTo(alternativeService), "Not alternative service.");
        }

        [Test]
        public void ShouldOnlyCreateOneSingleton()
        {
            Dependency.RegisterSingleton<ITest, Test>("test");

            ITest test1 = Dependency.Resolve<ITest>();
            ITest test2 = Dependency.Resolve<ITest>();

            Assert.That(test1, Is.Not.Null, "Expected non-null service.");
            Assert.That(test2, Is.Not.Null, "Expected non-null service.");
            Assert.That(test1, Is.SameAs(test2), "Only one instance of the singleton.");
        }

        [Test]
        public void ShouldAllowInstanceRegistration()
        {
            ITest test1 = new Test();

            Dependency.RegisterInstance<ITest>("test", test1);

            ITest test2 = Dependency.Resolve<ITest>();
            test2.TestMethod();

            Assert.That(test2, Is.Not.Null, "Expected non-null service.");
            Assert.That(test1, Is.SameAs(test2), "Returned registered instance");
        }

        [Test]
        public void ShouldAllowSettingOfTheContainer()
        {
            AutoMockingContainer mockContainer = new AutoMockingContainer(new MockRepository());
            Dependency.Container = mockContainer;

            Assert.That(Dependency.Container, Is.SameAs(mockContainer), "Correct container.");
        }
    }

    public interface ITest
    {
        void TestMethod();
    }

    public class Test : ITest
    {
        public void TestMethod() { }
    }
}
